home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / PROGRAMM / LOGO / H282.ZIP / MSWLOGO.ZIP / EXAMPLES.ZIP / PASCAL < prev    next >
Encoding:
Text File  |  1992-11-01  |  22.0 KB  |  895 lines

  1. TO BUGFIX :VAL
  2. OP INT :VAL
  3. END
  4. ;;; All references to BUGFIX are because products aren't integers on the Mac
  5.  
  6. TO ACOUNT :ARRAY
  7. OUTPUT COUNT :ARRAY
  8. END
  9.  
  10. TO GARRAY :ARRAY :INDEX
  11. OP ITEM BUGFIX :INDEX+1 :ARRAY
  12. END
  13.  
  14. TO PARRAY :ARRAY :INDEX :VALUE
  15. SETITEM BUGFIX :INDEX+1 :ARRAY :VALUE
  16. END
  17.  
  18. TO ARGLIST
  19. LOCAL [NAMES TYPE VARFLAG]
  20. MAKE "VARFLAG "FALSE
  21. IFBE "VAR [MAKE "VARFLAG "TRUE]
  22. MAKE "NAMES COMMALIST [ID]
  23. MUSTBE ":
  24. MAKE "TYPE TOKEN
  25. IF EQUALP :TYPE "PACKED [MAKE "TYPE TOKEN]
  26. IFELSE EQUALP :TYPE "ARRAY [MAKE "TYPE ARRAYTYPE] [TYPECHECK :TYPE]
  27. FOREACH :NAMES [NEWARG ? :TYPE NEWLNAME ? :VARFLAG]
  28. IFBEELSE "|;| [ARGLIST] [MUSTBE "|)|]
  29. END
  30.  
  31. TO ARRAYCOPY :TOTARGET :FROMTARGET
  32. LOCAL [TO FROM]
  33. MAKE "TO THING FIRST :TOTARGET
  34. MAKE "FROM THING FIRST :FROMTARGET
  35. FOR [I 0 [(ACOUNT :FROM) - 1]] [PARRAY :TO :I GARRAY :FROM :I]
  36. END
  37.  
  38. TO ARRAYSIZE :TYPE
  39. OUTPUT BUGFIX REDUCE "PRODUCT MAP [LAST ?] LAST :TYPE
  40. END
  41.  
  42. TO ARRAYTYPE
  43. LOCAL [RANGES TYPE]
  44. MUSTBE "|[|
  45. MAKE "RANGES COMMALIST [RANGE]
  46. MUSTBE "|]|
  47. MUSTBE "OF
  48. MAKE "TYPE TOKEN
  49. TYPECHECK :TYPE
  50. OUTPUT LIST :TYPE :RANGES
  51. END
  52.  
  53. TO BLOCK
  54. LOCAL [BLOCKNAME CODEINTO]
  55. MAKE "BLOCKNAME GENSYM
  56. DEFINE :BLOCKNAME [[]]
  57. MAKE "CODEINTO :BLOCKNAME
  58. BLOCKBODY "END
  59. OUTPUT (LIST :BLOCKNAME)
  60. END
  61.  
  62. TO BLOCKBODY :ENDWORD
  63. CODE STATEMENT
  64. IFBEELSE "|;| [BLOCKBODY :ENDWORD] [MUSTBE :ENDWORD]
  65. END
  66.  
  67. TO BOOLTOINT :EXPR
  68. OUTPUT (SE [( IFELSE] :EXPR [[1] [0] )])
  69. END
  70.  
  71. TO CHARTOINT :EXPR
  72. OUTPUT (SE [( ASCII FIRST BF] :EXPR [)] )
  73. END
  74.  
  75. TO CHARTOPRINT :CHARVAL
  76. OUTPUT FIRST BF :CHARVAL
  77. END
  78.  
  79. TO CODE :STUFF
  80. IF EMPTYP :STUFF [STOP]
  81. DEFINE :CODEINTO LPUT :STUFF TEXT :CODEINTO
  82. END
  83.  
  84. TO COMMALIST :TEST [:SOFAR []]
  85. LOCAL [RESULT TOKEN]
  86. MAKE "RESULT RUN :TEST
  87. IF EMPTYP :RESULT [OUTPUT :SOFAR]
  88. MAKE "TOKEN TOKEN
  89. IF EQUALP :TOKEN ", [OUTPUT (COMMALIST :TEST (LPUT :RESULT :SOFAR))]
  90. MAKE "PEEKTOKEN :TOKEN
  91. OUTPUT LPUT :RESULT :SOFAR
  92. END
  93.  
  94. TO COMPILE :FILE
  95. LOCAL "ERROR
  96. IF NAMEP "PEEKCHAR [ERN "PEEKCHAR]
  97. IF NAMEP "PEEKTOKEN [ERN "PEEKTOKEN]
  98. OPENREAD :FILE
  99. SETREAD :FILE
  100. IGNORE ERROR
  101. CATCH "ERROR [PROGRAM]
  102. MAKE "ERROR ERROR
  103. IF NOT EMPTYP :ERROR ~
  104.    [IF NOT EQUALP FIRST :ERROR 19 ~
  105.        [PR FIRST BF :ERROR]]
  106. SETREAD []
  107. CLOSE :FILE
  108. END
  109.  
  110. TO COPYOFARRAY :TARGET
  111. LOCAL [TO FROM]
  112. MAKE "FROM THING FIRST :TARGET
  113. MAKE "TO ARRAY ACOUNT :FROM
  114. FOR [I 0 [(ACOUNT :FROM) - 1]] [PARRAY :TO :I GARRAY :FROM :I]
  115. END
  116.  
  117. TO FUNCTION
  118. LOCAL [PROGNAME OLDIDLIST ARGLIST TYPE]
  119. LOCAL "CODEINTO
  120. MAKE "PROGNAME TOKEN
  121. PUSH "IDLIST (LIST :PROGNAME "FUNCTION NEWLNAME :PROGNAME)
  122. MAKE "OLDIDLIST :IDLIST
  123. LOCAL "IDLIST
  124. MAKE "IDLIST :OLDIDLIST
  125. MAKE "ARGLIST []
  126. MAKE LNAME :PROGNAME []
  127. IFBE "|(| [ARGLIST]
  128. MUSTBE ":
  129. MAKE "TYPE TOKEN
  130. TYPECHECK :TYPE
  131. MAKE LNAME :PROGNAME FPUT :TYPE THING LNAME :PROGNAME
  132. MUSTBE "|;|
  133. DEFINE LNAME :PROGNAME (LIST :ARGLIST)
  134. MAKE "CODEINTO LNAME :PROGNAME
  135. CODE [LOCAL "RESULT]
  136. PROGRAM1
  137. CODE [OUTPUT :RESULT]
  138. MUSTBE "|;|
  139. END
  140.  
  141. TO GETCHAR
  142. LOCAL "CHAR
  143. IF NAMEP "PEEKCHAR [MAKE "CHAR :PEEKCHAR ERN "PEEKCHAR OUTPUT :CHAR]
  144. IF EOFP [OUTPUT CHAR 1]
  145. OUTPUT RC1
  146. END
  147.  
  148. TO GETTYPE :WORD
  149. LOCAL "RESULT
  150. MAKE "RESULT LNAME1 :WORD :IDLIST
  151. IF NOT EMPTYP :RESULT [OUTPUT ITEM 2 :RESULT]
  152. PRINT SE [UNRECOGNIZED IDENTIFIER] :WORD
  153. THROW "ERROR
  154. END
  155.  
  156. TO ID
  157. LOCAL "TOKEN
  158. MAKE "TOKEN TOKEN
  159. IF LETTERP ASCII FIRST :TOKEN [OUTPUT :TOKEN]
  160. MAKE "PEEKTOKEN :TOKEN
  161. OUTPUT []
  162. END
  163.  
  164. TO IFBE :WANTED :ACTION
  165. LOCAL "TOKEN
  166. MAKE "TOKEN TOKEN
  167. IF EQUALP :TOKEN :WANTED [RUN :ACTION STOP]
  168. MAKE "PEEKTOKEN :TOKEN
  169. END
  170.  
  171. TO IFBEELSE :WANTED :ACTION :ELSE
  172. LOCAL "TOKEN
  173. MAKE "TOKEN TOKEN
  174. IF EQUALP :TOKEN :WANTED [RUN :ACTION STOP]
  175. MAKE "PEEKTOKEN :TOKEN
  176. RUN :ELSE
  177. END
  178.  
  179. TO LETTERP :CODE
  180. IF AND (:CODE > 64) (:CODE < 91) [OUTPUT "TRUE]
  181. OUTPUT AND (:CODE > 96) (:CODE < 123)
  182. END
  183.  
  184. TO LINDEX :BOUNDS :INDEX
  185. OUTPUT LINDEX1 (OFFSET PINTEGER FIRST :INDEX FIRST FIRST :BOUNDS) ~
  186.                BF :BOUNDS BF :INDEX
  187. END
  188.  
  189. TO LINDEX1 :SOFAR :BOUNDS :INDEX
  190. IF EMPTYP :BOUNDS [OUTPUT :SOFAR]
  191. OUTPUT LINDEX1 (NEXTINDEX :SOFAR ~
  192.                           LAST FIRST :BOUNDS ~
  193.                           PINTEGER FIRST :INDEX ~
  194.                           FIRST FIRST :BOUNDS) ~
  195.                BF :BOUNDS BF :INDEX
  196. END
  197.  
  198. TO LNAME :WORD
  199. LOCAL "RESULT
  200. MAKE "RESULT LNAME1 :WORD :IDLIST
  201. IF NOT EMPTYP :RESULT [OUTPUT ITEM 3 :RESULT]
  202. PRINT SE [UNRECOGNIZED IDENTIFIER] :WORD
  203. THROW "ERROR
  204. END
  205.  
  206. TO LNAME1 :WORD :LIST
  207. IF EMPTYP :LIST [OUTPUT []]
  208. IF EQUALP :WORD FIRST FIRST :LIST [OUTPUT FIRST :LIST]
  209. OUTPUT LNAME1 :WORD BF :LIST
  210. END
  211.  
  212. TO LPUSH :STACK :STUFF
  213. MAKE :STACK LPUT :STUFF THING :STACK
  214. END
  215.  
  216. TO MULT :A :B
  217. OUTPUT (SE [( PRODUCT] :A :B [)] )
  218. END
  219.  
  220. TO MUSTBE :WANTED
  221. LOCAL "TOKEN
  222. MAKE "TOKEN TOKEN
  223. IF EQUALP :TOKEN :WANTED [STOP]
  224. PRINT (SE "EXPECTED :WANTED "GOT :TOKEN)
  225. THROW "ERROR
  226. END
  227.  
  228. TO NEWARG :PNAME :TYPE :LNAME :VARFLAG
  229. IF RESERVEDP :PNAME [PR SE :PNAME [RESERVED WORD] THROW "ERROR]
  230. PUSH "IDLIST IFELSE :VARFLAG ~
  231.                     [(LIST :PNAME "VAR :LNAME :TYPE)] ~
  232.                     [(LIST :PNAME :TYPE :LNAME)]
  233. LPUSH "ARGLIST :LNAME
  234. LPUSH LNAME :PROGNAME IFELSE :VARFLAG [LIST "VAR :TYPE] [:TYPE]
  235. END
  236.  
  237. TO NEWLNAME :WORD
  238. IF MEMBERP :WORD :NAMESUSED [OUTPUT GENSYM]
  239. IF NAMEP WORD "% :WORD [OUTPUT GENSYM]
  240. PUSH "NAMESUSED :WORD
  241. OUTPUT WORD "% :WORD
  242. END
  243.  
  244. TO NEWVAR :PNAME :TYPE :LNAME
  245. IF RESERVEDP :PNAME [PR SE :PNAME [RESERVED WORD] THROW "ERROR]
  246. PUSH "IDLIST (LIST :PNAME :TYPE :LNAME)
  247. CODE LIST "LOCAL WORD "" :LNAME
  248. IF LISTP :TYPE [CODE (LIST "MAKE WORD "" :LNAME "ARRAY ARRAYSIZE :TYPE)]
  249. END
  250.  
  251. TO NEXTINDEX :OLD :FACTOR :NEW :OFFSET
  252. OUTPUT (SE [( SUM] (MULT :OLD :FACTOR) (OFFSET :NEW :OFFSET) [)] )
  253. END
  254.  
  255. TO NUMBER :NUM
  256. LOCAL "CHAR
  257. MAKE "CHAR GETCHAR
  258. IF EQUALP :CHAR ". ~
  259.    [MAKE "CHAR GETCHAR ~
  260.     IFELSE EQUALP :CHAR ". ~
  261.            [MAKE "PEEKTOKEN ".. OUTPUT :NUM] ~
  262.            [MAKE "PEEKCHAR :CHAR OUTPUT NUMBER WORD :NUM ".]]
  263. IF EQUALP :CHAR "E [OUTPUT NUMBER WORD :NUM TWOCHAR "E [+ -]]
  264. IF NUMBERP :CHAR [OUTPUT NUMBER WORD :NUM :CHAR]
  265. MAKE "PEEKCHAR :CHAR
  266. OUTPUT :NUM
  267. END
  268.  
  269. TO NUMTYPE :NUMBER
  270. IF MEMBERP ". :NUMBER [OUTPUT "REAL]
  271. IF MEMBERP "E :NUMBER [OUTPUT "REAL]
  272. OUTPUT "INTEGER
  273. END
  274.  
  275. TO OFFSET :A :B
  276. OUTPUT (SE [( DIFFERENCE] :A :B [)] )
  277. END
  278.  
  279. TO OPSETUP
  280. PPROP "|=| "BINARY [EQUALP 2 [BOOLEAN []] 1]
  281. PPROP "|<>| "BINARY [[NOT EQUALP] 2 [BOOLEAN []] 1]
  282. PPROP "|<| "BINARY [LESSP 2 [BOOLEAN []] 1]
  283. PPROP "|>| "BINARY [GREATERP 2 [BOOLEAN []] 1]
  284. PPROP "|<=| "BINARY [[NOT GREATERP] 2 [BOOLEAN []] 1]
  285. PPROP "|>=| "BINARY [[NOT LESSP] 2 [BOOLEAN []] 1]
  286. PPROP "|+| "BINARY [SUM 2 2]
  287. PPROP "|-| "BINARY [DIFFERENCE 2 2]
  288. PPROP "OR "BINARY [OR 2 [BOOLEAN BOOLEAN] 2]
  289. PPROP "|*| "BINARY [PRODUCT 2 3]
  290. PPROP "|/| "BINARY [QUOTIENT 2 [REAL []] 3]
  291. PPROP "DIV "BINARY [[INT QUOTIENT] 2 [INTEGER INTEGER] 3]
  292. PPROP "MOD "BINARY [REMAINDER 2 [INTEGER INTEGER] 3]
  293. PPROP "AND "BINARY [AND 2 [BOOLEAN BOOLEAN] 3]
  294. PPROP "|+| "UNARY [[] 1 4]
  295. PPROP "|-| "UNARY [MINUS 1 4]
  296. PPROP "NOT "UNARY [NOT 1 [BOOLEAN BOOLEAN] 4]
  297. MAKE "IDLIST [[TRUNC FUNCTION INT] ~
  298.               [ROUND FUNCTION ROUND] [RANDOM FUNCTION RANDOM]]
  299. MAKE "INT [INTEGER REAL]
  300. MAKE "ROUND [INTEGER REAL]
  301. MAKE "RANDOM [INTEGER INTEGER]
  302. END
  303.  
  304. TO PARRAYASSIGN :NAME :TYPE :TARGET
  305. LOCAL [RIGHT RTYPE RLNAME RTARGET]
  306. MAKE "RIGHT TOKEN
  307. IF EQUALP FIRST :RIGHT "' [OUTPUT PSTRINGASSIGN :TARGET :TYPE (BL BF :RIGHT)]
  308. MAKE "RTYPE GETTYPE :RIGHT
  309. MAKE "RLNAME LNAME :RIGHT
  310. IFELSE EQUALP :RTYPE "VAR [PVARRIGHT] [MAKE "RTARGET (LIST :RLNAME)]
  311. IF EQUALP :TYPE :RTYPE [OUTPUT (LIST "ARRAYCOPY :TARGET :RTARGET)]
  312. PR (SE "ARRAYS :NAME "AND :RIGHT [UNEQUAL TYPES])
  313. THROW "ERROR
  314. END
  315.  
  316. TO PARRAYDATA :PNAME :TYPE :TARGET
  317. LOCAL "INDEX
  318. MUSTBE "|[|
  319. MAKE "INDEX COMMALIST [PEXPR]
  320. MUSTBE "|]|
  321. MAKE "INDEX LINDEX LAST :TYPE :INDEX
  322. MAKE "TYPE FIRST :TYPE
  323. MAKE "TARGET SE :TARGET :INDEX
  324. OUTPUT PMAYBECHAR :TYPE (LIST "PTHING :TARGET)
  325. END
  326.  
  327. TO PASSIGN
  328. LOCAL [NAME TYPE INDEX VALUE LNAME TARGET]
  329. MAKE "NAME TOKEN
  330. MAKE "INDEX []
  331. IFBE "|[| [MAKE "INDEX COMMALIST [PEXPR] MUSTBE "|]|]
  332. MUSTBE "|:=|
  333. MAKE "LNAME LNAME :NAME
  334. MAKE "TYPE GETTYPE :NAME
  335. OUTPUT PASSIGN1
  336. END
  337.  
  338. TO PASSIGN1
  339. IFELSE EQUALP :TYPE "VAR [PVARASSIGN :NAME] [MAKE "TARGET (LIST :LNAME)]
  340. IF AND (LISTP :TYPE) (EMPTYP :INDEX) [OUTPUT PARRAYASSIGN :NAME :TYPE :TARGET]
  341. IF LISTP :TYPE [MAKE "INDEX LINDEX LAST :TYPE :INDEX MAKE "TYPE FIRST :TYPE]
  342. IF NOT EMPTYP :INDEX [MAKE "TARGET SE :TARGET :INDEX]
  343. MAKE "VALUE PEXPR
  344. IF EQUALP :TYPE "REAL [MAKE "VALUE PREAL :VALUE]
  345. IF EQUALP :TYPE "INTEGER [MAKE "VALUE PINTEGER :VALUE]
  346. IF EQUALP :TYPE "CHAR [MAKE "VALUE PCHAR :VALUE]
  347. IF EQUALP :TYPE "BOOLEAN [MAKE "VALUE PBOOLEAN :VALUE]
  348. OUTPUT (SE (LIST "PMAKE :TARGET) :VALUE)
  349. END
  350.  
  351. TO PBOOLEAN :EXPR
  352. IF EQUALP FIRST :EXPR "BOOLEAN [OUTPUT LAST :EXPR]
  353. PR SE LAST :COND [NOT TRUE OR FALSE]
  354. THROW "ERROR
  355. END
  356.  
  357. TO PCHAR :EXPR
  358. IF EQUALP FIRST :EXPR "CHAR [OUTPUT LAST :EXPR]
  359. PR SE LAST :COND [NOT CHARACTER VALUE]
  360. THROW "ERROR
  361. END
  362.  
  363. TO PCHARDATA :TOKEN
  364. IF NOT EQUALP COUNT :TOKEN 3 [PR SE :TOKEN [NOT SINGLE CHARACTER] THROW "ERROR]
  365. OUTPUT LIST "CHAR WORD "" :TOKEN
  366. END
  367.  
  368. TO PCHECKTYPE :WANT :LEFT :RIGHT
  369. IF NOT EQUALP :WANT :LEFT [PR (SE :LEFT "ISN'T :WANT) THROW "ERROR]
  370. IF NOT EQUALP :WANT :RIGHT [PR (SE :RIGHT "ISN'T :WANT) THROW "ERROR]
  371. END
  372.  
  373. TO PCLOSE
  374. WHILE [(LAST FIRST :OPSTACK) > 0] [PPOPOP]
  375. IGNORE POP "OPSTACK
  376. MAKE "PARENLEVEL :PARENLEVEL - 1
  377. END
  378.  
  379. TO PDATA :TOKEN
  380. LOCAL [TYPE LNAME TARGET]
  381. IF EQUALP :TOKEN "TRUE [OUTPUT [BOOLEAN "TRUE]]
  382. IF EQUALP :TOKEN "FALSE [OUTPUT [BOOLEAN "FALSE]]
  383. IF EQUALP FIRST :TOKEN "' [OUTPUT PCHARDATA :TOKEN]
  384. IF NUMBERP :TOKEN [OUTPUT LIST NUMTYPE :TOKEN :TOKEN]
  385. MAKE "TYPE GETTYPE :TOKEN
  386. IF EMPTYP :TYPE [PR SE [UNDEFINED SYMBOL] :TOKEN THROW "ERROR]
  387. MAKE "LNAME LNAME :TOKEN
  388. IFELSE EQUALP :TYPE "VAR [PVARASSIGN :TOKEN] [MAKE "TARGET (LIST :LNAME)]
  389. IF EQUALP :TYPE "FUNCTION [OUTPUT PFUNCALL :TOKEN]
  390. IF LISTP :TYPE [OUTPUT PARRAYDATA :TOKEN :TYPE :TARGET]
  391. OUTPUT PMAYBECHAR :TYPE LIST "PTHING :TARGET
  392. END
  393.  
  394. TO PEXPR
  395. LOCAL [OPSTACK DATASTACK PARENLEVEL]
  396. MAKE "OPSTACK [[POPEN 1 0]]
  397. MAKE "DATASTACK []
  398. MAKE "PARENLEVEL 0
  399. OUTPUT PEXPR1
  400. END
  401.  
  402. TO PEXPR1
  403. LOCAL [TOKEN OP]
  404. MAKE "TOKEN TOKEN
  405. WHILE [EQUALP :TOKEN "|(|] [POPEN MAKE "TOKEN TOKEN]
  406. MAKE "OP PGETUNARY :TOKEN
  407. IF NOT EMPTYP :OP [OUTPUT PEXPROP :OP]
  408. PUSH "DATASTACK PDATA :TOKEN
  409. MAKE "TOKEN TOKEN
  410. WHILE [AND (:PARENLEVEL > 0) (EQUALP :TOKEN "|)| )] [PCLOSE MAKE "TOKEN TOKEN]
  411. MAKE "OP PGETBINARY :TOKEN
  412. IF NOT EMPTYP :OP [OUTPUT PEXPROP :OP]
  413. MAKE "PEEKTOKEN :TOKEN
  414. PCLOSE
  415. IF NOT EMPTYP :OPSTACK [PR [TOO MANY OPERATORS] THROW "ERROR]
  416. IF NOT EMPTYP BF :DATASTACK [PR [TOO MANY OPERANDS] THROW "ERROR]
  417. OUTPUT POP "DATASTACK
  418. END
  419.  
  420. TO PEXPROP :OP
  421. WHILE [(LAST :OP) < (1 + LAST FIRST :OPSTACK)] [PPOPOP]
  422. PUSH "OPSTACK :OP
  423. OUTPUT PEXPR1
  424. END
  425.  
  426. TO PFOR
  427. LOCAL [VAR INIT STEP FINAL ACTION]
  428. MAKE "VAR TOKEN
  429. MUSTBE "|:=|
  430. MAKE "INIT PINTEGER PEXPR
  431. MAKE "STEP 1
  432. IFBEELSE "DOWNTO [MAKE "STEP -1] [MUSTBE "TO]
  433. MAKE "FINAL PINTEGER PEXPR
  434. MUSTBE "DO
  435. MAKE "ACTION STATEMENT
  436. OUTPUT (LIST "FOR (LIST LNAME :VAR :INIT :FINAL :STEP) :ACTION)
  437. END
  438.  
  439. TO PFUNCALL :PNAME
  440. LOCAL [LNAME VARTYPES]
  441. MAKE "LNAME LNAME :PNAME
  442. MAKE "VARTYPES THING :LNAME
  443. IF EMPTYP BF :VARTYPES [OUTPUT LIST FIRST :VARTYPES :LNAME]
  444. MUSTBE "|(|
  445. OUTPUT LIST FIRST :VARTYPES FPUT :LNAME PROCARGS BF :VARTYPES
  446. END
  447.  
  448. TO PFUNSET
  449. LOCAL [NAME TYPE INDEX VALUE LNAME TARGET]
  450. MAKE "NAME TOKEN
  451. MAKE "INDEX []
  452. IF NOT EQUALP :NAME :PROGNAME [PR SE [ASSIGN TO WRONG FUNCTION] :NAME THROW "ERROR]
  453. MUSTBE "|:=|
  454. MAKE "LNAME "RESULT
  455. MAKE "TYPE FIRST THING LNAME :NAME
  456. OUTPUT PASSIGN1
  457. END
  458.  
  459. TO PGETBINARY :TOKEN
  460. OUTPUT GPROP :TOKEN "BINARY
  461. END
  462.  
  463. TO PGETUNARY :TOKEN
  464. OUTPUT GPROP :TOKEN "UNARY
  465. END
  466.  
  467. TO PIF
  468. LOCAL [COND THEN ELSE]
  469. MAKE "COND PBOOLEAN PEXPR
  470. MUSTBE "THEN
  471. MAKE "THEN STATEMENT
  472. MAKE "ELSE []
  473. IFBE "ELSE [MAKE "ELSE STATEMENT]
  474. OUTPUT (SE "IFELSE :COND (LIST :THEN) (LIST :ELSE))
  475. END
  476.  
  477. TO PINTEGER :PVAL
  478. LOCAL "TYPE
  479. MAKE "TYPE FIRST :PVAL
  480. IF EQUALP :TYPE "INTEGER [OUTPUT LAST :PVAL]
  481. IF EQUALP :TYPE "BOOLEAN [OUTPUT BOOLTOINT LAST :PVAL]
  482. IF EQUALP :TYPE "CHAR [OUTPUT CHARTOINT LAST :PVAL]
  483. PR SE LAST :PVAL [ISN'T ORDINAL]
  484. THROW "ERROR
  485. END
  486.  
  487. TO PMAKE :TARGET :VALUE
  488. IFELSE EMPTYP BF :TARGET ~
  489.        [MAKE FIRST :TARGET :VALUE] ~
  490.        [PARRAY TARGETVAR FIRST :TARGET RUN BF :TARGET :VALUE]
  491. END
  492.  
  493. TO PMAYBECHAR :TYPE :VAL
  494. IF EQUALP :TYPE "CHAR [OUTPUT LIST "CHAR SE "PVARTOCHAR :VAL]
  495. OUTPUT LIST :TYPE :VAL
  496. END
  497.  
  498. TO PNEWTYPE :OP :LTYPE :RTYPE
  499. LOCAL "TYPE
  500. MAKE "TYPE (IFELSE (COUNT :OP) > 3 [ITEM 3 :OP] [[[] []]])
  501. IF EMPTYP :LTYPE [MAKE "LTYPE :RTYPE]
  502. IF NOT EMPTYP LAST :TYPE [PCHECKTYPE LAST :TYPE :LTYPE :RTYPE]
  503. IF AND (EQUALP :LTYPE "REAL) (EQUALP :RTYPE "INTEGER) [MAKE "RTYPE "REAL]
  504. IF AND (EQUALP :LTYPE "INTEGER) (EQUALP :RTYPE "REAL) [MAKE "LTYPE "REAL]
  505. IF NOT EQUALP :LTYPE :RTYPE [PR [TYPE CLASH] THROW "ERROR]
  506. IF EMPTYP LAST :TYPE ~
  507.    [IF NOT MEMBERP :RTYPE [INTEGER REAL] [PR [NONARITHMETIC TYPE] THROW "ERROR]]
  508. IF EMPTYP FIRST :TYPE [OUTPUT :RTYPE]
  509. OUTPUT FIRST :TYPE
  510. END
  511.  
  512. TO POPEN
  513. PUSH "OPSTACK [POPEN 1 0]
  514. MAKE "PARENLEVEL :PARENLEVEL + 1
  515. END
  516.  
  517. TO PPOPOP
  518. LOCAL [OP FUNCTION ARGS LEFT RIGHT TYPE]
  519. MAKE "OP POP "OPSTACK
  520. MAKE "FUNCTION FIRST :OP
  521. MAKE "ARGS FIRST BF :OP
  522. MAKE "RIGHT POP "DATASTACK
  523. MAKE "LEFT (IFELSE EQUALP :ARGS 2 [POP "DATASTACK] [[[] []]])
  524. MAKE "TYPE PNEWTYPE :OP FIRST :LEFT FIRST :RIGHT
  525. PUSH "DATASTACK LIST :TYPE (SE [(] :FUNCTION LAST :LEFT LAST :RIGHT [)] )
  526. END
  527.  
  528. TO PPROCCALL
  529. LOCAL [PNAME LNAME VARTYPES]
  530. MAKE "PNAME TOKEN
  531. MAKE "LNAME LNAME :PNAME
  532. MAKE "VARTYPES THING :LNAME
  533. IF EMPTYP :VARTYPES [OUTPUT (LIST :LNAME)]
  534. MUSTBE "|(|
  535. OUTPUT FPUT :LNAME PROCARGS :VARTYPES
  536. END
  537.  
  538. TO PREAL :PVAL
  539. IF EQUALP FIRST :PVAL "REAL [OUTPUT LAST :PVAL]
  540. OUTPUT PINTEGER :PVAL
  541. END
  542.  
  543. TO PREPEAT
  544. LOCAL [COND BLOCKNAME CODEINTO]
  545. MAKE "BLOCKNAME GENSYM
  546. DEFINE :BLOCKNAME [[]]
  547. MAKE "CODEINTO :BLOCKNAME
  548. BLOCKBODY "UNTIL
  549. MAKE "COND PBOOLEAN PEXPR
  550. OUTPUT (LIST "DOUNTIL (LIST :BLOCKNAME) :COND)
  551. END
  552.  
  553. TO PRINTSIZE :SIZE :STUFF
  554. IF NOT (:SIZE > COUNT :STUFF) [OUTPUT :STUFF]
  555. OUTPUT PRINTSIZE :SIZE WORD "| | :STUFF
  556. END
  557.  
  558. TO PROCARG :TYPE
  559. LOCAL "RESULT
  560. IF EQUALP FIRST :TYPE "VAR [OUTPUT PROCVARARG LAST :TYPE]
  561. IF LISTP :TYPE [OUTPUT PROCARRAYARG :TYPE]
  562. MAKE "RESULT PEXPR
  563. IF EQUALP :TYPE "REAL [MAKE "RESULT PREAL :RESULT]
  564. IF EQUALP :TYPE "INTEGER [MAKE "RESULT PINTEGER :RESULT]
  565. IF EQUALP :TYPE "CHAR [MAKE "RESULT PCHAR :RESULT]
  566. IF EQUALP :TYPE "BOOLEAN [MAKE "RESULT PBOOLEAN :RESULT]
  567. OUTPUT :RESULT
  568. END
  569.  
  570. TO PROCARGS :TYPES
  571. LOCAL "NEXT
  572. IF EMPTYP :TYPES [MUSTBE "|)| OUTPUT []]
  573. MAKE "NEXT PROCARG FIRST :TYPES
  574. IF NOT EMPTYP BF :TYPES [MUSTBE ",]
  575. OUTPUT SE :NEXT PROCARGS BF :TYPES
  576. END
  577.  
  578. TO PROCARRAYARG :TYPE
  579. LOCAL [PNAME TYPE LNAME TARGET]
  580. MAKE "PNAME TOKEN
  581. MAKE "TYPE GETTYPE :PNAME
  582. MAKE "LNAME LNAME :PNAME
  583. IFELSE EQUALP :TYPE "VAR [PVARASSIGN] [MAKE "TARGET (LIST :LNAME)]
  584. OUTPUT LIST "COPYOFARRAY :TARGET
  585. END
  586.  
  587. TO PROCEDURE
  588. LOCAL [PROGNAME OLDIDLIST CODEINTO ARGLIST]
  589. MAKE "PROGNAME TOKEN
  590. PUSH "IDLIST (LIST :PROGNAME "PROCEDURE NEWLNAME :PROGNAME)
  591. MAKE "OLDIDLIST :IDLIST
  592. LOCAL "IDLIST
  593. MAKE "IDLIST :OLDIDLIST
  594. MAKE "CODEINTO LNAME :PROGNAME
  595. MAKE "ARGLIST []
  596. MAKE LNAME :PROGNAME []
  597. IFBE "|(| [ARGLIST]
  598. MUSTBE "|;|
  599. DEFINE LNAME :PROGNAME (LIST :ARGLIST)
  600. PROGRAM1
  601. MUSTBE "|;|
  602. END
  603.  
  604. TO PROCVARARG :FTYPE
  605. LOCAL [PNAME TYPE LNAME TARGET]
  606. MAKE "PNAME TOKEN
  607. MAKE "TYPE GETTYPE :PNAME
  608. MAKE "LNAME LNAME :PNAME
  609. IFELSE EQUALP :TYPE "VAR [PVARASSIGN :PNAME] [MAKE "TARGET (LIST :LNAME)]
  610. IF AND (LISTP :TYPE) (WORDP :FTYPE) [OUTPUT PROCVARARGARRAY :FTYPE :TYPE :TARGET]
  611. IF NOT EQUALP :TYPE :FTYPE [PR SE :PNAME [ARG WRONG TYPE] THROW "ERROR]
  612. OUTPUT (LIST :TARGET)
  613. END
  614.  
  615. TO PROCVARARGARRAY :FTYPE :TYPE :TARGET
  616. IF NOT EQUALP :FTYPE FIRST :TYPE [PR SE :PNAME [ARG WRONG TYPE] THROW "ERROR]
  617. LOCAL "INDEX
  618. MUSTBE "|[|
  619. MAKE "INDEX COMMALIST [PEXPR]
  620. MUSTBE "|]|
  621. MAKE "INDEX LINDEX LAST :TYPE :INDEX
  622. OUTPUT (LIST SE :TARGET :INDEX)
  623. END
  624.  
  625. TO PROGRAM
  626. LOCAL [PROGNAME OLDIDLIST NAMESUSED CODEINTO]
  627. MAKE "NAMESUSED []
  628. MUSTBE "PROGRAM
  629. MAKE "PROGNAME TOKEN
  630. MUSTBE "|(|
  631. IGNORE COMMALIST [ID]
  632. MUSTBE "|)|
  633. MUSTBE "|;|
  634. IF NOT NAMEP "IDLIST [OPSETUP]
  635. MAKE "OLDIDLIST :IDLIST
  636. LOCAL "IDLIST
  637. MAKE "IDLIST :OLDIDLIST
  638. PUSH "IDLIST (LIST :PROGNAME "PROGRAM NEWLNAME :PROGNAME)
  639. DEFINE LNAME :PROGNAME [[]]
  640. MAKE "CODEINTO LNAME :PROGNAME
  641. PROGRAM1
  642. MUSTBE ".
  643. END
  644.  
  645. TO PROGRAM1
  646. IFBE "VAR [VARPART]
  647. TRYPROCPART
  648. MUSTBE "BEGIN
  649. BLOCKBODY "END
  650. END
  651.  
  652. TO PRUN :PROGNAME
  653. RUN FPUT WORD "% :PROGNAME []
  654. END
  655.  
  656. TO PSTRINGASSIGN :TARGET :TYPE :STRING
  657. IF NOT EQUALP FIRST :TYPE "CHAR [STRINGLOSE]
  658. IF NOT EMPTYP BF LAST :TYPE [STRINGLOSE]
  659. IF NOT EQUALP (LAST FIRST LAST :TYPE) (COUNT :STRING) [STRINGLOSE]
  660. OUTPUT (LIST "STRINGCOPY :TARGET WORD "" :STRING)
  661. END
  662.  
  663. TO PTHING :TARGET
  664. IF EMPTYP BF :TARGET [OUTPUT THING FIRST :TARGET]
  665. OUTPUT GARRAY TARGETVAR FIRST :TARGET RUN BF :TARGET
  666. END
  667.  
  668. TO PUSH :STACK :ITEM
  669. MAKE :STACK FPUT :ITEM THING :STACK
  670. END
  671.  
  672. TO PVARASSIGN :NAME
  673. LOCAL "ID
  674. MAKE "ID LNAME1 :NAME :IDLIST
  675. MAKE "TYPE LAST :ID
  676. MAKE "TARGET WORD ": :LNAME
  677. END
  678.  
  679. TO PVARRIGHT
  680. LOCAL "ID
  681. MAKE "ID LNAME1 :RIGHT :IDLIST
  682. MAKE "RTYPE LAST :ID
  683. MAKE "RTARGET WORD ": :RLNAME
  684. END
  685.  
  686. TO PVARTOCHAR :VALUE
  687. IF NUMBERP :VALUE [OUTPUT CHAR :VALUE]
  688. OUTPUT :VALUE
  689. END
  690.  
  691. TO PWHILE
  692. LOCAL [COND ACTION]
  693. MAKE "COND PBOOLEAN PEXPR
  694. MUSTBE "DO
  695. MAKE "ACTION STATEMENT
  696. OUTPUT (LIST "WHILE :COND :ACTION)
  697. END
  698.  
  699. TO PWRITE
  700. MUSTBE "|(|
  701. OUTPUT (SE [( TYPE] PWRITE1 [)] )
  702. END
  703.  
  704. TO PWRITE1
  705. LOCAL [RESULT TOKEN]
  706. MAKE "RESULT PWRITE2
  707. MAKE "TOKEN TOKEN
  708. IF EQUALP :TOKEN "|)| [OUTPUT :RESULT]
  709. IF NOT EQUALP :TOKEN ", [PR SE [EXPECTED , GOT] :TOKEN THROW "ERROR]
  710. OUTPUT SE :RESULT PWRITE1
  711. END
  712.  
  713. TO PWRITE2
  714. LOCAL "RESULT
  715. MAKE "RESULT PWRITE3
  716. IFBE ": [MAKE "RESULT (SE "PRINTSIZE TOKEN BF BF :RESULT)]
  717. OUTPUT :RESULT
  718. END
  719.  
  720. TO PWRITE3
  721. LOCAL [TOKEN RESULT]
  722. MAKE "TOKEN TOKEN
  723. IF EQUALP FIRST :TOKEN "' [OUTPUT (LIST "PRINTSIZE 1 "FIRST (LIST BL BF :TOKEN))]
  724. MAKE "PEEKTOKEN :TOKEN
  725. MAKE "RESULT PEXPR
  726. IF EQUALP FIRST :RESULT "CHAR [OUTPUT SE [PRINTSIZE 1 CHARTOPRINT] LAST :RESULT]
  727. IF EQUALP FIRST :RESULT "BOOLEAN [OUTPUT SE [PRINTSIZE 1] LAST :RESULT]
  728. IF EQUALP FIRST :RESULT "INTEGER [OUTPUT SE [PRINTSIZE 10] LAST :RESULT]
  729. OUTPUT SE [PRINTSIZE 20] LAST :RESULT
  730. END
  731.  
  732. TO PWRITELN
  733. LOCAL "TOKEN
  734. MAKE "TOKEN TOKEN
  735. MAKE "PEEKTOKEN :TOKEN
  736. IF NOT EQUALP :TOKEN "|(| [OUTPUT [PRINT []]]
  737. OUTPUT SE PWRITE [PRINT []]
  738. END
  739.  
  740. TO RANGE
  741. LOCAL [FIRST LAST]
  742. MAKE "FIRST RANGE1
  743. MUSTBE "..
  744. MAKE "LAST RANGE1
  745. IF :FIRST > :LAST ~  
  746.    [PR (SE [ARRAY BOUNDS NOT INCREASING:] :FIRST ".. :LAST) THROW "ERROR]
  747. OUTPUT LIST :FIRST (1 + :LAST - :FIRST)
  748. END
  749.  
  750. TO RANGE1
  751. LOCAL "BOUND
  752. MAKE "BOUND TOKEN
  753. IF EQUALP FIRST :BOUND "' [OUTPUT ASCII FIRST BF :BOUND]
  754. IF EQUALP :BOUND "|-| [MAKE "BOUND MINUS TOKEN]
  755. IF EQUALP :BOUND INT :BOUND [OUTPUT :BOUND]
  756. PR SE [ARRAY BOUND NOT ORDINAL:] :BOUND
  757. THROW "ERROR
  758. END
  759.  
  760. TO RC1
  761. LOCAL "RESULT
  762. MAKE "RESULT RC
  763. TYPE :RESULT
  764. OUTPUT :RESULT
  765. END
  766.  
  767. TO RESERVEDP :WORD
  768. OUTPUT MEMBERP :WORD [AND ARRAY BEGIN CASE CONST DIV DO DOWNTO ELSE END ~
  769.                       FILE FOR FORWARD FUNCTION GOTO IF IN LABEL MOD NIL ~
  770.                       NOT OF PACKED PROCEDURE PROGRAM RECORD REPEAT SET ~
  771.                       THEN TO TYPE UNTIL VAR WHILE WITH]
  772. END
  773.  
  774. TO SKIPCOMMENT
  775. IF EQUALP GETCHAR "|}| [STOP]
  776. SKIPCOMMENT
  777. END
  778.  
  779. TO STATEMENT
  780. LOCAL [TOKEN TYPE]
  781. MAKE "TOKEN TOKEN
  782. IF EQUALP :TOKEN "BEGIN [OUTPUT BLOCK]
  783. IF EQUALP :TOKEN "FOR [OUTPUT PFOR]
  784. IF EQUALP :TOKEN "IF [OUTPUT PIF]
  785. IF EQUALP :TOKEN "WHILE [OUTPUT PWHILE]
  786. IF EQUALP :TOKEN "REPEAT [OUTPUT PREPEAT]
  787. IF EQUALP :TOKEN "WRITE [OUTPUT PWRITE]
  788. IF EQUALP :TOKEN "WRITELN [OUTPUT PWRITELN]
  789. MAKE "PEEKTOKEN :TOKEN
  790. IF MEMBERP :TOKEN [|;| END UNTIL] [OUTPUT []]
  791. MAKE "TYPE GETTYPE :TOKEN
  792. IF EMPTYP :TYPE [PR SE :TOKEN [CAN'T BEGIN STATEMENT] THROW "ERROR]
  793. IF EQUALP :TYPE "PROCEDURE [OUTPUT PPROCCALL]
  794. IF EQUALP :TYPE "FUNCTION [OUTPUT PFUNSET]
  795. OUTPUT PASSIGN
  796. END
  797.  
  798. TO STRING :STRING
  799. LOCAL "CHAR
  800. MAKE "CHAR GETCHAR
  801. IF NOT EQUALP :CHAR "' [OUTPUT STRING WORD :STRING :CHAR]
  802. MAKE "CHAR GETCHAR
  803. IF EQUALP :CHAR "' [OUTPUT STRING WORD :STRING :CHAR]
  804. MAKE "PEEKCHAR :CHAR
  805. OUTPUT WORD :STRING "'
  806. END
  807.  
  808. TO STRINGCOPY :TOTARGET :FROM
  809. LOCAL [I TO]
  810. MAKE "TO THING FIRST :TOTARGET
  811. MAKE "I 0
  812. FOREACH :FROM [PARRAY :TO :I (WORD "' ? "') MAKE "I :I + 1]
  813. END
  814.  
  815. TO STRINGLOSE
  816. PR SE :NAME [NOT STRING ARRAY OR WRONG SIZE]
  817. THROW "ERROR
  818. END
  819.  
  820. TO TARGETVAR :WORD
  821. IF EQUALP FIRST :WORD ": [OUTPUT THING THING BF :WORD]
  822. OUTPUT THING :WORD
  823. END
  824.  
  825. TO TOKEN
  826. LOCAL [TOKEN CHAR]
  827. IF NAMEP "PEEKTOKEN [MAKE "TOKEN :PEEKTOKEN ERN "PEEKTOKEN OUTPUT :TOKEN]
  828. MAKE "CHAR GETCHAR
  829. IF EQUALP :CHAR "|{| [SKIPCOMMENT OUTPUT TOKEN]
  830. IF EQUALP :CHAR CHAR 32 [OUTPUT TOKEN]
  831. IF EQUALP :CHAR CHAR 13 [OUTPUT TOKEN]
  832. IF EQUALP :CHAR CHAR 10 [OUTPUT TOKEN]
  833. IF EQUALP :CHAR "' [OUTPUT STRING "']
  834. IF MEMBERP :CHAR [+ - * / = ( , ) |[| |]| |;|] [OUTPUT :CHAR]
  835. IF EQUALP :CHAR "|<| [OUTPUT TWOCHAR "|<| [= >]]
  836. IF EQUALP :CHAR "|>| [OUTPUT TWOCHAR "|>| [=]]
  837. IF EQUALP :CHAR ". [OUTPUT TWOCHAR ". [.]]
  838. IF EQUALP :CHAR ": [OUTPUT TWOCHAR ": [=]]
  839. IF NUMBERP :CHAR [OUTPUT NUMBER :CHAR]
  840. IF LETTERP ASCII :CHAR [OUTPUT TOKEN1 UC :CHAR]
  841. PR SE [UNRECOGNIZED CHARACTER:] :CHAR
  842. THROW "ERROR
  843. END
  844.  
  845. TO TOKEN1 :TOKEN
  846. LOCAL "CHAR
  847. MAKE "CHAR GETCHAR
  848. IF OR LETTERP ASCII :CHAR NUMBERP :CHAR [OUTPUT TOKEN1 WORD :TOKEN UC :CHAR]
  849. MAKE "PEEKCHAR :CHAR
  850. OUTPUT :TOKEN
  851. END
  852.  
  853. TO TRYPROCPART
  854. IFBEELSE "PROCEDURE ~
  855.          [PROCEDURE TRYPROCPART] ~
  856.          [IFBE "FUNCTION [FUNCTION TRYPROCPART]]
  857. END
  858.  
  859. TO TWOCHAR :OLD :OK
  860. LOCAL "CHAR
  861. MAKE "CHAR GETCHAR
  862. IF MEMBERP :CHAR :OK [OUTPUT WORD :OLD :CHAR]
  863. MAKE "PEEKCHAR :CHAR
  864. OUTPUT :OLD
  865. END
  866.  
  867. TO TYPECHECK :TYPE
  868. IF MEMBERP :TYPE [REAL INTEGER CHAR BOOLEAN] [STOP]
  869. PRINT SE [UNDEFINED TYPE] :TYPE
  870. THROW "ERROR
  871. END
  872.  
  873. TO UC :CHAR
  874. LOCAL "CODE
  875. MAKE "CODE ASCII :CHAR
  876. IF OR (:CODE < 97) (:CODE > 122) [OUTPUT :CHAR]
  877. OUTPUT CHAR :CODE - 32
  878. END
  879.  
  880. TO VARPART
  881. LOCAL [TOKEN NAMELIST]
  882. MAKE "TOKEN TOKEN
  883. MAKE "PEEKTOKEN :TOKEN
  884. IF RESERVEDP :TOKEN [STOP]
  885. MAKE "NAMELIST COMMALIST [ID]
  886. MUSTBE ":
  887. MAKE "TOKEN TOKEN
  888. IF EQUALP :TOKEN "PACKED [MAKE "TOKEN TOKEN]
  889. IFELSE EQUALP :TOKEN "ARRAY [MAKE "TOKEN ARRAYTYPE] [TYPECHECK :TOKEN]
  890. MUSTBE "|;|
  891. FOREACH :NAMELIST [NEWVAR ? :TOKEN NEWLNAME ?]
  892. VARPART
  893. END
  894.  
  895.